`include "DEFINE.v"
module EX(
input wire [5:0]op_i,
input wire [31:0]regaData,
input wire [31:0]regbData,
input wire regcWrite_i,
input wire [4:0]regcAddr_i,
input wire rst,
output reg [31:0]regcData,
output reg [31:0]hi,
output reg [31:0]lo,
output wire regcWrite,
output wire [4:0]regcAddr,
//mem
output wire [5:0]op,
output wire[31:0]memAddr,
output wire[31:0]memData
);

reg [63:0] re;
reg f1;
reg f2;
reg f;
reg [31:0]ra;
reg [31:0]rb;

always@(*)
begin
	if(rst == `Enable)
		regcData = `Zero;
	else
	begin
		case(op)
		//TYPE I
		`ORI:
			regcData = regaData | regbData;
		`ADDI:
			regcData = regaData + regbData;
		`ANDI:
			regcData = regaData & regbData;
		`XORI:
			regcData = regaData ^ regbData;
		`LUI:
			regcData = regbData;

		//TYPE R
		`ADD:
			regcData = regaData + regbData;
		`SUB:
			regcData = regaData - regbData;
		`AND:
			regcData = regaData & regbData;
		`OR:
			regcData = regaData | regbData;
		`XOR:
			regcData = regaData ^ regbData;
		`SLL:
			regcData = regaData << regbData[4:0];
		`SRL:
			regcData=regaData>>regbData[4:0];
		`SRA:
			regcData=($signed(regaData)>>>regbData[4:0]);
		
		//TYPE J
		`JAL:
			regcData=regaData;	
	
		`SLT:
			regcData = $signed(regaData)<$signed(regbData) ? 1:0;
		`JALR:
			regcData = regaData;
		`MULT:
begin
			{hi,lo}=$signed(regaData) * $signed(regbData);
end
		`MULTU:
			{hi,lo} = regaData * regbData;
		`DIV:
begin
			hi = $signed(regaData) % $signed(regbData);
			lo = $signed(regaData) / $signed(regbData);
end
		`DIVU:
begin
			hi = regaData % regbData;
			lo = regaData / regbData;
end
		`MFHI:
			regcData = regaData;
		`MFLO:
			regcData = regbData;
		`MTHI:
			hi = regaData;
		`MTLO:
			lo = regaData;

		default:
			regcData = `Zero;
		endcase
	end
end
assign op = op_i;
assign regcWrite = regcWrite_i;
assign regcAddr = regcAddr_i;
assign memAddr = regaData;
assign memData = regbData;
endmodule


